package cn.yunbamboos.rest.service.converter;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.yunbamboos.exception.AppException;
import cn.yunbamboos.rest.service.IRestService;
import cn.yunbamboos.rest.service.ISession;
import cn.yunbamboos.rest.service.dto.in.BaseInDTO;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;


public class RequestConverterJSONInDTO extends RequestConverterInDTO {

    private static final Logger logger = LoggerFactory.getLogger(RequestConverterJSONInDTO.class);

    public RequestConverterJSONInDTO() {
        super(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN);
    }

    @Override
    public BaseInDTO converter() {
        ISession session = sessionContainer.getSession();
        if (ObjUtil.isNull(session)) {
            throw AppException.c("session is null");
        }
        IRestService service = session.getService();
        // 读取请求内容
        HttpServletRequest request = session.getRequest();
        String method = request.getMethod();
        if ("GET".equals(method)) {
            JSONObject json = readGET(request);
            BaseInDTO in = service.createInDTO().create(json);
            in.setSession(session);
            return in;
        }
        if ("POST".equals(method)) {
            JSONObject json = readPOST(request);
            BaseInDTO in = service.createInDTO().create(json);
            in.setSession(session);
            return in;
        }
        throw AppException.c("Request Converter DTO is unrealized");
    }

    private JSONObject readGET(HttpServletRequest request) {
        JSONObject json = new JSONObject();
        Map<String, String[]> params = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : params.entrySet()) {
            String key = entry.getKey();
            String[] values = entry.getValue();
            if (values.length == 1) {
                json.put(key, values[0]);
            } else {
                JSONArray array = new JSONArray();
                array.addAll(Arrays.asList(values));
                json.put(key, array);
            }
        }
        return json;
    }

    private JSONObject readPOST(HttpServletRequest request) {
        try {
            ServletInputStream in = request.getInputStream();
            String body = StreamUtils.copyToString(in, StandardCharsets.UTF_8);
            if (StrUtil.isNotBlank(body)) {
                return JSON.parseObject(body);
            }
        } catch (IOException e) {
            logger.error("read POST request error", e);
        }
        return new JSONObject();
    }


}
